package com.beasts.ant.auth.config.oauth.impl;

import com.beasts.ant.auth.common.exception.OauthUserNotFoundException;
import com.beasts.ant.auth.entity.Authority;
import com.beasts.ant.auth.entity.User;
import com.beasts.ant.auth.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;

/**
 * 自定义实现 oauth2 用户信息查询
 *
 * @author Locker
 * @date 11/05/2018 11:01 AM
 * @since 1.0
 */
@Component("userDetailsService")
public class OauthUserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    @Transactional
    public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
        String lowerCaseLogin = login.toLowerCase();
        User userFromDatabase = userRepository.findByUsernameCaseInsensitive(lowerCaseLogin);

        if (userFromDatabase == null) {
            throw new OauthUserNotFoundException("Oauth: User " + lowerCaseLogin + " was not found in the database");
        }

        // 获取用户所有权限并添加到SpringSecurity需要的集合中
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for (Authority authority : userFromDatabase.getAuthorities()) {
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(authority.getName());
            grantedAuthorities.add(grantedAuthority);
        }

        // 返回SpringSecurity需要的用户对象
        return new org.springframework.security.core.userdetails.User(
                userFromDatabase.getUsername(),
                userFromDatabase.getPassword(),
                grantedAuthorities
        );
    }
}
